package com.powergisol.gis.geom;
import	java.util.jar.JarInputStream;

import com.powergisol.core.math.Dot;
import com.powergisol.core.math.Plane;
import com.vividsolutions.jts.geom.Coordinate;

import com.vividsolutions.jts.geom.Envelope;

import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.WKTWriter;

import java.util.ArrayList;

import java.util.Arrays;
import java.util.List;

public class GeoPolygon extends GeoType{

    private Coordinate[] coordinates;

    public GeoPolygon(Coordinate[] coordinates){
        checkIsClosed(coordinates);
    }

    private void checkIsClosed(Coordinate[] coordinates){

        if(!coordinates[coordinates.length-1].equals3D(coordinates[0])){

            Coordinate[] copy = Arrays.copyOf(coordinates,coordinates.length+1);
            copy[copy.length-1]  = coordinates[0];
            setCoordinates(copy);
        }else{
            setCoordinates(coordinates);
        }

    }


    public void setCoordinates(Coordinate[] coordinates) {

        if(coordinates.length<4){
            throw new RuntimeException("一个面至少由3个点构成!");
        }

        this.coordinates = coordinates;
    }

    public Coordinate[] getCoordinates() {
        return this.coordinates;
    }

    public GeoPolygon(double[] x, double[] y){

        if(x==null||y==null){
            throw new NullPointerException("x or y must be requeid! ");
        }

        if(x.length!=y.length){

            throw new IllegalArgumentException("x和y的数组长度必须一致");
        }

        List<Coordinate> list = new ArrayList<>();
        for (int i = 0; i < x.length; i++) {
            Coordinate coordinate = new Coordinate(x[i],y[i]);
            list.add(coordinate);
        }

        setCoordinates(list.toArray(new Coordinate[list.size()]));
    }



    public GeoPolygon(double[] xAndy){

        if(xAndy==null){
            throw new NullPointerException(" 数组不能为空! ");
        }

        if(xAndy.length%2!=0){
            throw new IllegalArgumentException(" 数组长度必须为偶数! ");
        }
        List<Coordinate> list = new ArrayList<>();

        for (int i = 0; i < xAndy.length; i++) {
            Coordinate coordinate = new Coordinate(xAndy[i],xAndy[++i]);
            list.add(coordinate);
        }

        setCoordinates(list.toArray(new Coordinate[list.size()]));

    }

    public GeoPolygon(double[][] xAndy){
        if(xAndy==null){
            throw new NullPointerException(" 数组不能为空! ");
        }

        List<Coordinate> list = new ArrayList<>();

        for(int i = 0; i < xAndy.length; i++){
            double[] xy = xAndy[i];
            if(xy.length!=2){
                throw new IllegalArgumentException("每组数组长度必须为2");
            }

            Coordinate coordinate = new Coordinate(xy[0],xy[1]);
            list.add(coordinate);
        }

        setCoordinates(list.toArray(new Coordinate[list.size()]));
    }

    public GeoPolygon(List<Dot> dots){

        List<Coordinate> coordinates = new ArrayList<>();
        dots.forEach(dot -> {
            Coordinate coordinate = new Coordinate(dot.getX(),dot.getY(),dot.getZ());
            coordinates.add(coordinate);
        });
        checkIsClosed(coordinates.toArray(new Coordinate[coordinates.size()]));
    }


    @Override
    public Polygon  toGeometry() {
        return geometryFactory.createPolygon(this.coordinates);
    }

    @Override
    public String toWKT() {
        return new WKTWriter().write(toGeometry());
    }


    /**
     * 获取范围
     * @return
     */
//    public Double[] getEnvelope(){
//
//        Envelope envelope = toGeometry().getEnvelopeInternal();
//
//        List<Double> doubles = new ArrayList<>();
//
//        doubles.add(envelope.getMaxX());
//        doubles.add(envelope.getMinX());
//        doubles.add(envelope.getMaxY());
//        doubles.add(envelope.getMinY());
//
//        return doubles.toArray(new Double[doubles.size()]);
//    }

    @Override
    public String toString() {
        return toGeometry().toText();
    }

    /**
     * 转换成空间解析几何的面
     * @return
     */
    public Plane toPlane(){

        List<Dot> dots = new ArrayList<>();
        Coordinate[] coordinates = getCoordinates();
        for (int i = 0; i < coordinates.length; i++) {
            Dot dot = new Dot(coordinates[i].x,coordinates[i].y, coordinates[i].z);
            dots.add(dot);
        }

        return new Plane(dots);
    }
}
